package com.isp.common.utils;

import com.google.common.collect.Sets;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author Linsy
 * @version 1.0
 * @created 2024/7/21.
 */
public class CollectionUtils {

    public static <T> boolean isEmpty(Collection<T> collect) {
        return collect == null || collect.isEmpty();
    }

    public static <T> boolean isNotEmpty(Collection<T> collect) {
        return !isEmpty(collect);
    }

    public static <K, V> boolean isEmpty(Map<K, V> map) {
        return map == null || map.isEmpty();
    }

    public static <K, V> boolean isNotEmpty(Map<K, V> map) {
        return !isEmpty(map);
    }

    public static <T> T[] toArray(Collection<T> collect, Class<T[]> clazz) {
        if (collect == null) {
            throw null;
        }
        if (clazz == null) {
            return null;
        }
        Object[] data = collect.toArray();
        return Arrays.copyOf(data, data.length, clazz);
    }

    public static <T> boolean containsElement(Collection<T> collect, T elem) {
        if (elem == null || isEmpty(collect)) {
            return false;
        }
        return collect.contains(elem);
    }

    public static <E> List<E> concatList(List<E>... array) {
        if (array == null || array.length < 1) {
            return Collections.emptyList();
        }
        List<E> newList = new ArrayList<>();
        for (List<E> e : array) {
            if (isNotEmpty(e)) {
                newList.addAll(e);
            }
        }
        return newList;
    }

    /**
     * 如果元素不为空, 则添加进集合
     *
     * @param c
     * @param e
     * @param <T>
     */
    public static <T> void addIf(Collection<T> c, T e) {
        if (e != null) {
            c.add(e);
        }
    }

    public static int sizeOf(Collection c) {
        if (c == null) {
            return 0;
        }
        return c.size();
    }

    public static int sizeOf(Map m) {
        if (m == null) {
            return 0;
        }
        return m.size();
    }

    /**
     * 取集合中的第一个元素
     *
     * @param c
     * @param <T>
     * @return
     */
    public static <T> T getFirst(Collection<T> c) {
        if (isEmpty(c)) {
            return null;
        }

        Iterator<T> it = c.iterator();
        if (it.hasNext()) {
            return it.next();
        }
        return null;
    }

    /**
     * 取集合中的第一个元素
     *
     * @param list
     * @param <T>
     * @return
     */
    public static <T> T getFirst(List<T> list) {
        if (isEmpty(list)) {
            return null;
        }
        return list.get(0);
    }

    /**
     * 取集合中的最后一个元素
     *
     * @param list
     * @param <T>
     * @return
     */
    public static <T> T getLast(List<T> list) {
        if (isEmpty(list)) {
            return null;
        }
        return list.get(list.size() - 1);
    }

    /**
     * 数组转成Set集合
     *
     * @param elements
     * @param <E>
     * @return
     */
    public static <E> Set<E> toSet(E... elements) {
        if (ArrayUtils.isEmpty(elements)) {
            return new HashSet<>();
        }
        Set<E> set = Sets.newHashSetWithExpectedSize(elements.length);
        if (ArrayUtils.isNotEmpty(elements)) {
            Collections.addAll(set, elements);
        }
        return set;
    }

    /**
     * 集合转成map. 注意: 如果key相同, 则旧的会被覆盖
     *
     * @param c
     * @param keyFunction
     * @param <K>
     * @param <T>
     * @return
     */
    public static <K, T> Map<K, T> toMap(Collection<T> c, Function<T, K> keyFunction) {
        if (CollectionUtils.isEmpty(c)) {
            return new HashMap<>();
        }
        Map<K, T> map = new HashMap<>();
        for (T t : c) {
            K key = keyFunction.apply(t);
            map.put(key, t);
        }

        return map;
    }

    public static <K, T> Map<K, List<T>> toListMap(Collection<T> c, Function<T, K> keyFunction) {
        if (isEmpty(c)) {
            return new HashMap<>();
        }

        Map<K, List<T>> map = new HashMap<>();
        for (T t : c) {
            K key = keyFunction.apply(t);
            map.computeIfAbsent(key, k -> new ArrayList<>()).add(t);
        }
        return map;
    }

    public static <T, V> Set<V> getFieldValues(Collection<T> c, Function<T, V> valueFunction) {
        return c.stream().map(valueFunction).collect(Collectors.toSet());
    }

    /**
     * 删除列表中为null的元素，如果列表本身为null，则返回空列表
     *
     * @param list
     * @param <E>
     * @return
     */
    public static <E> List<E> removeNullElements(List<E> list) {
        if (CollectionUtils.isEmpty(list)) {
            return list;
        }
        list.removeIf(Objects::isNull);
        return list;
    }

    /**
     * 根据元素个数预估Map的大小
     */
    public static int predictMapSize(int potentialKeyNum) {
        if (potentialKeyNum <= 0) {
            return 0;
        } else {
            return potentialKeyNum * 4 / 3 + 1;
        }
    }
}
